#include "stdafx.h"


Camera::Camera(void) :
	mPosition(0, 0, -10),
	mTarget(0, 0, 1),
	mUp(0, 1, 0),
	mRight(1, 0, 0)
{
}


Camera::~Camera(void)
{
}


void Camera::addVelocity(float xVal, float yVal, float zVal)
{
	mPosition += mTarget*zVal;
	mPosition += mRight*xVal;
	mPosition.y += yVal;
}


void Camera::rotate(float x, float y)
{
	D3DXMATRIX matRotation;
	if( y != 0 )
	{
		D3DXMatrixRotationAxis( &matRotation, &mRight, D3DXToRadian(y));
		D3DXVec3TransformCoord( &mTarget, &mTarget, &matRotation );
		D3DXVec3TransformCoord( &mUp, &mUp, &matRotation );
	}

	if( x != 0 )
	{
		D3DXMatrixRotationAxis( &matRotation, &D3DXVECTOR3(0,1,0), D3DXToRadian(x) );
		D3DXVec3TransformCoord( &mTarget, &mTarget, &matRotation );
		D3DXVec3TransformCoord( &mUp, &mUp, &matRotation );
	}
}


void Camera::update()
{
	D3DXMATRIX view;
	D3DXMatrixIdentity( &view );

	D3DXVec3Normalize( &mTarget, &mTarget );
	D3DXVec3Cross( &mRight, &mUp, &mTarget );
	D3DXVec3Normalize( &mRight, &mRight );
	D3DXVec3Cross( &mUp, &mTarget, &mRight );
	D3DXVec3Normalize( &mUp, &mUp );

	view._11 = mRight.x;
	view._12 = mUp.x;
	view._13 = mTarget.x;
	view._14 = 0.0f;

	view._21 = mRight.y;
	view._22 = mUp.y;
	view._23 = mTarget.y;
	view._24 = 0.0f;

	view._31 = mRight.z;
	view._32 = mUp.z;
	view._33 = mTarget.z;
	view._34 = 0.0f;

	view._41 = -D3DXVec3Dot( &mPosition, &mRight );
	view._42 = -D3DXVec3Dot( &mPosition, &mUp );
	view._43 = -D3DXVec3Dot( &mPosition, &mTarget );
	view._44 =  1.0f;

	globals::d3dDevice->SetTransform( D3DTS_VIEW, &view ); 
}


void Camera::toLua()
{
	using luabind::def;
	using luabind::class_;

	luabind::module(lua::State())
	[
		class_<Camera>("Camera").
		def(luabind::constructor<>()).
		def("move", &Camera::addVelocity).
		def("rotate", &Camera::rotate).
		def("update", &Camera::update)
	];
}